package com.dhcc.DRGsHosp.facade.impl;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.inject.Inject;
import javax.inject.Named;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.dayatang.domain.InstanceFactory;
import org.openkoala.koala.commons.InvokeResult;
import org.openkoala.security.application.UserApplication;
import org.openkoala.security.core.domain.EncryptService;
import org.openkoala.security.core.domain.Role;
import org.openkoala.security.core.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;

import com.dhcc.DRGsHosp.application.DepartmentApplication;
import com.dhcc.DRGsHosp.application.WardApplication;
import com.dhcc.DRGsHosp.core.domain.Department;
import com.dhcc.DRGsHosp.facade.UserInfoFileUploadFacade;
import com.dhcc.DRGsHosp.infra.util.ExcelUtil;

/**
 * @title		:FileUploadFacadeImpl.java
 * @description	:
 * @author		:chenhanlin
 * @date		:2017年07月13日
 * @version     :1.0
 * @copyright   :DHCC 2016-2017 
 */
@Scope("session")
@Named("drgsHospFacadeImplchl20170713")
public class UserInfoFileUploadFacadeImpl implements UserInfoFileUploadFacade,Serializable {
	private static final long serialVersionUID = -1474745132287740189L;
	
	@Autowired
	private UserApplication userApplication ;

	@Inject
	private DepartmentApplication departmentApplication;
	@Inject
	private WardApplication wardApplication;
	
	
	
	protected static EncryptService passwordEncryptService;
	protected static EncryptService getPasswordEncryptService() {
        if (passwordEncryptService == null) {
            passwordEncryptService = InstanceFactory.getInstance(EncryptService.class);
        }
        return passwordEncryptService;
    }
	 

/**
 *  @Description：用户批量导入
 *  @Author lhj 
 *  @see com.dhcc.DRGsHosp.facade.UserInfoFileUploadFacade#userImport(java.lang.String, java.lang.String)
 */
	@Override
	public InvokeResult userImport(String filePath, String currentUser) {
		StringBuffer message = new StringBuffer() ;//返回前台的信息
		// 查询所有角色,获取角色列表
		List<Role> roleList = Role.findAll() ;
		// rolesMap 存储 roleId - roleDesc 
		Map<String,String> rolesMap = new HashMap<>() ;
		for (int i=0 ; i<roleList.size(); i++) {
			String roleName=roleList.get(i).getName()==null?null:roleList.get(i).getName().toString();
			String roleId=roleList.get(i).getId()==null?null:roleList.get(i).getId().toString();
			rolesMap.put(roleName,roleId) ;
		}
		// 查询所有科室信息
		List<Department> depList = departmentApplication.getAllDeps() ;
		// 科室描述-科室编码
		List<String> depCodeList = new ArrayList<>();
		for (int i=0 ; i < depList.size() ; i++) {
			depCodeList.add(depList.get(i).getDepCode()) ;
		}
		// 查询所有病区信息
		List<Map<String,Object>> wardList = wardApplication.findWardDescWithDep() ;
		// 病区描述-病区编码
		List<String> wardCodeList = new ArrayList<>();
		for (int i=0; i<wardList.size() ; i++) {
			if(wardList.get(i).get("ward_code")!=null){
				wardCodeList.add(wardList.get(i).get("ward_code").toString()) ;
			}
		}
		Sheet sheet = ExcelUtil.readExcelSheet(filePath,0) ;
		int rowNum=sheet.getLastRowNum();//行数
		Row row = null ;
		// 存放文件的表头位置
		Map<String,Object> titlemap = new HashMap<>();
		// 标题行
		Row headrow = sheet.getRow(0);
		int headCount = headrow.getLastCellNum();
		Cell cell=null;
		for (int i = 0; i < headCount; i++) {
			cell = headrow.getCell((short) i);
			titlemap.put(cell.getStringCellValue(), i);
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		// 循环获取用户信息
		try {
			message.setLength(0);
			for(int i = 1 ; i <= rowNum ; i++) {
				row=sheet.getRow(i);
				// 该行为空时解析下一行
				if(null == row) {
					continue ;
				}
				// 保存用户信息
				String salt = UUID.randomUUID().toString();
				cell = row.getCell((int) (titlemap.get("用户账号") != null ? titlemap.get("用户账号"):1000));
				String userAccount = ExcelUtil.getCellValue(cell) ;
				User user = new User(userAccount) ;
				cell = row.getCell((int) (titlemap.get("用户名称") != null ? titlemap.get("用户名称"):1000));
				String name = ExcelUtil.getCellValue(cell) ;
				user.setName(name) ;
				user.setValidityDate(sdf.parse("2050-12-31"));//用户有效期
				if(User.getByUserAccount(userAccount) != null) {
					// 用户已经存在，执行删除操作
					User userOld = User.getByUserAccount(userAccount) ;
					userApplication.deleteUser(userOld) ;
				}
				user.setSalt(salt);
				String password = getPasswordEncryptService().encryptPassword("888888", salt + userAccount);
				user.setPassword(password);
				cell = row.getCell((int) (titlemap.get("用户描述") != null ? titlemap.get("用户描述"):1000));
				String description = ExcelUtil.getCellValue(cell) ;
				user.setDescription(description);
				cell = row.getCell((int) (titlemap.get("状态") != null ? titlemap.get("状态"):1000));
				String disabled = ExcelUtil.getCellValue(cell) ;
				user.setDisabled(Boolean.getBoolean(disabled));
				cell = row.getCell((int) (titlemap.get("邮箱") != null ? titlemap.get("邮箱"):1000));
				String email = ExcelUtil.getCellValue(cell) ;
				user.setEmail(email);
				cell = row.getCell((int) (titlemap.get("电话") != null ? titlemap.get("电话"):1000));
				String telePhone = ExcelUtil.getCellValue(cell) ;
				user.setTelePhone(telePhone);
				cell = row.getCell((int) (titlemap.get("有效截止日期") != null ? titlemap.get("有效截止日期"):1000));
				if(cell != null){
					Date validityDate = cell.getDateCellValue();
					user.setValidityDate(validityDate);
				}
				// 版本
				user.setVersion(0);
				user.setCreateOwner(currentUser);
				userApplication.saveUser(user) ;
				Long userId = null ;
				userId = userApplication.queryUserId(user);
				user.setId(userId);
				// 角色授权
				cell = row.getCell((int) (titlemap.get("角色") != null ? titlemap.get("角色"):1000));
				String roleName = ExcelUtil.getCellValue(cell) ;
				if(roleName==null) {
					return InvokeResult.failure("角色名称不能为空！");
				}
				roleName=roleName.replace("，", ",");
				if(roleName!=null){
					String[] roleNameArray = roleName.split("，") ;
					for(int j = 0; j<roleNameArray.length; j ++) {
						Role role = Role.getRoleBy(roleNameArray[j]) ;
						if( null == role) {
							message.append("第" + (i+1) +"行"+userAccount+"用户，没有相应的"+roleNameArray[j]+"角色，请检查<br> " ); 
							continue ;
						}
						Map<String,Object> condition = new HashMap<>() ;
						condition.put("version", "0") ;
						condition.put("actorId", userId) ;
						condition.put("authority", role.getId()) ;
						try {
							userApplication.grantRolesToUser(condition) ;
						} catch (Exception e) {
							e.printStackTrace();
							message.append("为" + (i+1) +"行"+userAccount+"用户授角色时报错，请检查<br> " ); 
						}
					}
					// 先判断是否授予科室角色
					if(Arrays.asList(roleNameArray).contains("科室")) { 
						// 授权科室
						cell = row.getCell((int) (titlemap.get("授权科室代码") != null ? titlemap.get("授权科室代码"):1000));
						String depCode = ExcelUtil.getCellValue(cell)==null?"":ExcelUtil.getCellValue(cell) ;
						depCode = depCode.replace("，", ",");
						// 判断授权的科室是否存在
						String[] depCodes = depCode.split(",") ;
						// 校验是否成功
						boolean flag = true ;
						for(int j = 0; j < depCodes.length; j++) {
							if(!depCodeList.contains(depCodes[j])) {
								message.append("第" + (i+1) +"行授权科室代码"+depCodes[j]+"不存在，无法完成对科室的授权<br> " ) ; 
								flag = false ;
								break ;
							}
						}
						if(flag) {
							user.setDepYb(depCode) ;
						}
			            cell = row.getCell((int) (titlemap.get("授权科室描述") != null ? titlemap.get("授权科室描述"):1000));
						String depDesc = ExcelUtil.getCellValue(cell) ;
						user.setDepDesc(depDesc) ;
						try {
							userApplication.grantDepToUser(user) ;
						} catch (Exception e) {
							message.append("为用户"+user.getUserAccount()+"授权科室时报错，请检查<br> " );
						}
					}
					// 先判断是否授予科室角色
					if(Arrays.asList(roleNameArray).contains("病区")) {
						// 授权病区 
						cell = row.getCell((int) (titlemap.get("授权病区代码") != null ? titlemap.get("授权病区代码"):1000));
						String wardCode = ExcelUtil.getCellValue(cell)==null?"": ExcelUtil.getCellValue(cell);
						wardCode = wardCode.replace("，", ",");
						// 判断授权的病区是否存在
						String[] wardCodes = wardCode.split(",") ;
						// 校验是否成功
						boolean flag = true ;
						for(int j = 0; j < wardCodes.length; j++) {
							if(!wardCodeList.contains(wardCodes[j])) {
								message.append("第" + (i+1) +"行授权病区代码"+wardCodes[j]+"不存在，无法完成对病区的授权<br> " ) ; 
								flag = false ;
								break ;
							}
						}
						if(flag) {
							user.setWardCode(wardCode);
						}
						cell = row.getCell((int) (titlemap.get("授权病区描述") != null ? titlemap.get("授权病区描述"):1000));
						String wardDesc = ExcelUtil.getCellValue(cell) ;
						user.setWardDesc(wardDesc);
					}
					try {
						userApplication.grantWardToUser(user) ;
					} catch (Exception e) {
						message.append("为用户"+user.getUserAccount()+"授权病区时报错，请检查<br> " );
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			ExcelUtil.deleteFile(filePath) ;
		}
		return InvokeResult.success(message) ;
	}
}
